/*
 * cli.c
 *
 * Created: 08/01/2014 11:09:31
 *  Author: usuario
 */ 

#include <rtos.h>
#include <dronus.h>

#include "cli.h"


const char welcome_message[] = "DRONUS command server.\r\nType Help to view a list of registered commands.\r\n\r\n>";

extern void vRegisterCLICommands( void );

freertos_usart_if cli_interface;
char InputBuffer[cmdMAX_INPUT_SIZE];

void cli_task(void *pvParameters);

xSemaphoreHandle xSemaphore_CliTX;

void CLI_setup ( void )
{
	const sam_usart_opt_t usart_settings = {
		CLI_SPEED,
		US_MR_CHRL_8_BIT,
		US_MR_PAR_NO,
		US_MR_NBSTOP_1_BIT,
		US_MR_CHMODE_NORMAL,
		0 /* Only used in IrDA mode. */
	};
	
	freertos_peripheral_options_t driver_options;
	driver_options.interrupt_priority=USART_IRQ_PRIORITY;
	driver_options.operation_mode=USART_RS232;
	driver_options.options_flags= ( WAIT_RX_COMPLETE );
	driver_options.receive_buffer_size=cmdMAX_INPUT_SIZE;
	driver_options.receive_buffer=(uint8_t *) InputBuffer;
	
	cli_interface = freertos_usart_serial_init(CLI_USART_BASE, &usart_settings, &driver_options);
	
	xSemaphore_CliTX = xSemaphoreCreateBinary();
	configASSERT(xSemaphore_CliTX);
	xSemaphoreTake(xSemaphore_CliTX, 0);
				
	vRegisterCLICommands();
		
	xTaskCreate(cli_task, "CLI",	CLI_TASK_STACK_SIZE,	(void *) 0,	CLI_TASK_PRIORITY,	NULL);
}
			 
void cli_task( void *pvParameters )
{
	long lBytes, lByte = 0;
	uint8_t InChar, InputIndex = 0;
	uint8_t LocalBuffer[cmdMAX_INPUT_SIZE];
	char *OutputBuffer;
	BaseType_t xMoreDataToFollow;
	uint8_t loops;

	OutputBuffer=FreeRTOS_CLIGetOutputBuffer();

	strcpy(OutputBuffer, welcome_message);
	
	freertos_usart_write_packet_async(cli_interface, (uint8_t *) OutputBuffer, strlen((char *) OutputBuffer), CLI_WRITE_MAX_BLOCK_TIME, xSemaphore_CliTX);
	
	for( ;; )
	{
		xSemaphoreTake(xSemaphore_CliTX, CLI_WRITE_MAX_BLOCK_TIME);
		lBytes = freertos_usart_serial_read_packet(cli_interface, (uint8_t *) InputBuffer, cmdMAX_INPUT_SIZE-1, CLI_READ_MAX_BLOCK_TIME);
		freertos_usart_write_packet_async(cli_interface, (uint8_t *) InputBuffer, lBytes, CLI_WRITE_MAX_BLOCK_TIME, xSemaphore_CliTX);
		
		lByte = 0;
		while( lByte < lBytes )
		{
			InChar = InputBuffer[ lByte ];
			lByte++;
			
			if( InChar == '\n'  || InChar == '\r')
			{
				loops=0;
				LocalBuffer[ InputIndex ]='\0';
				do 
				{
					xSemaphoreTake(xSemaphore_CliTX, CLI_WRITE_MAX_BLOCK_TIME);
					if (loops == 0 )
					{
						strcpy(OutputBuffer,"\r\n");
						xMoreDataToFollow = FreeRTOS_CLIProcessCommand( (char *) LocalBuffer, (char *) &OutputBuffer[2], configCOMMAND_INT_MAX_OUTPUT_SIZE-3);
					} else xMoreDataToFollow = FreeRTOS_CLIProcessCommand( (char *) LocalBuffer, (char *) OutputBuffer, configCOMMAND_INT_MAX_OUTPUT_SIZE-1);
					if (xMoreDataToFollow == pdFALSE )
					{
							OutputBuffer[  strlen( (char *) OutputBuffer ) ] = '>';
							OutputBuffer[  strlen( (char *) OutputBuffer ) +1 ] = '\0';
					}
					freertos_usart_write_packet_async(cli_interface, (uint8_t *) OutputBuffer, strlen( (char *) OutputBuffer ), CLI_WRITE_MAX_BLOCK_TIME, xSemaphore_CliTX);
					loops++;
				} while( xMoreDataToFollow != pdFALSE );
				InputIndex = 0;
				lByte=lBytes;
			}
			else
			{
				if( InChar == '\b' || InChar == 127 )
				{
					/* Backspace was pressed.  Erase the last character in the string - if any. */
					if( InputIndex > 0 )
					{
						InputIndex--;
						LocalBuffer[ InputIndex ] = '\0';
					}
				}
				else
				{
					/* A character was entered.  Add it to the string */
					if( InputIndex < cmdMAX_INPUT_SIZE )
					{
						LocalBuffer[ InputIndex ] = InChar;
						InputIndex++;
					}
				}
			}
		}
	}
}